package com.example.demo.service.impl;

import com.alibaba.druid.support.json.JSONUtils;
import com.example.demo.entity.LoginUser;
import com.example.demo.mapper.InterfaceMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
//鉴权规则
@Component
public class MySecurityMetadataSource implements SecurityMetadataSource {
    /**
     * 当前系统所有接口资源对象，放在这里相当于一个缓存的功能。
     * 你可以在应用启动时将该缓存给初始化，也可以在使用过程中加载数据，这里我就不多展开说明了
     */
    @Autowired
    private InterfaceMapper interfaceMapper;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) {
        //白名单放行,就不走DecisionManger
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        if(requestUrl.equals("/login")){
            return null;
        }
        if(requestUrl.contains("/websocket/")){
            return null;
        }
        if(requestUrl.equals("/sys/user/register")){
            return null;
        }
        if(requestUrl.equals("/error")){
            return Collections.singletonList(new SecurityConfig("noLogin"));
        }
        if(requestUrl.indexOf("/img")!=-1){
            return null;
        }
        //业务逻辑匹配处理
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Map<String,Object> map=new HashMap();
        List<Map<String,Object>> interIds= interfaceMapper.getAllInterface(map);
        // 该对象是Spring Security帮我们封装好的，可以通过该对象获取request等信息
        FilterInvocation filterInvocation = (FilterInvocation) object;
        HttpServletRequest request = filterInvocation.getRequest();
        // 遍历所有权限资源，以和当前请求进行匹配
        for (Map<String, Object> interId : interIds) {
            // 因为我们url资源是这种格式：GET:/API/user/test/{id}，冒号前面是请求方法，冒号后面是请求路径，所以要字符串拆分
            // 因为/API/user/test/{id}这种路径参数不能直接equals来判断请求路径是否匹配，所以需要用Ant类来匹配
            AntPathRequestMatcher ant = new AntPathRequestMatcher(interId.get("interPath").toString());
            // 如果请求方法和请求路径都匹配上了，则代表找到了这个请求所需的权限资源
            if (ant.matches(request)) {
                // 将我们权限资源id返回，这个SecurityConfig就是ConfigAttribute一个简单实现
                return Collections.singletonList(new SecurityConfig(interId.get("interId").toString()));
            }
        }
        // 走到这里就代表该请求无需授权即可访问，返回空
        return Collections.singletonList(new SecurityConfig("noLogin"));
    }


    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
